﻿using Bot.Domain.SessionChat;


using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bot.Domain.Report
{
    public class ChatbotAgentItem : BaseReportInfoItem
    {
        [JsonIgnore]
        public string Type { get; set; }
        public int Chats { get; set; }
        public double AvgTime { get; set; }
        public double AvgScore { get; set; }
        [JsonIgnore]
        public double Transferred { get; set; }
        [JsonConverter(typeof(LongConvert))]
        public long TotalChatTime { get; set; }

        public override string GetValue(int i)
        {
            switch (i)
            {
                case 0:
                    return this.Type.ToString();
                    break;
                case 1:
                    return this.Chats.ToString();
                    break;
                case 2:
                    return this.AvgTime.ToString();
                    break;
                case 3:
                    return this.AvgScore.ToString();
                    break;
                //case 4:
                //    return this.Transferred.ToString();
                //    break;
                case 4:
                    return format(this.TotalChatTime);
                    break;
                default:
                    return "";
            }
        }

        private string format(long time)
        {
            long longValue = Convert.ToInt64(time);
            //D.HH:MM:SS
            //D为天，HH为小时，MM为分钟，SS为秒
            long second = 0;
            long day = Math.DivRem(longValue, 60 * 60 * 24, out second);
            long hour = Math.DivRem(second, 60 * 60, out second);
            long minute = Math.DivRem(second, 60, out second);

            return string.Format("{0}.{1}:{2}:{3}", day, hour.ToString("00"), minute.ToString("00"), second.ToString("00"));
        }

    }
    public class ChatbotAgentInfo : BaseReportInfo<ChatbotAgentItem>
    {
        public int Chats { get; set; }
        public double AvgTime { get; set; }
        public double AvgScore { get; set; }
        [JsonIgnore]
        public double TotalTransferred { get; set; }
        [JsonIgnore]
        public new EnumReportDataType DataType { get { return dataType; } }
        [JsonIgnore]
        public long TotalChatTime { get; set; }

        public ChatbotAgentItem Agent { get; set; }
        public ChatbotAgentItem Bot { get; set; }
          
        [JsonIgnore]
        public override IList<ChatbotAgentItem> DataList { get { return dataList; } }

        [JsonIgnore]
        public override List<string> FieldList
        {
            get
            {
                return new List<string>() {
                    "","Chats","Avg. Chat Time","Avg. Rating Score","Total Chat Time"
                };
            }
        }
        public override string GetValue(int i)
        {
            switch (i)
            {
                case 0:
                    return "";
                    break;
                case 1:
                    return this.Chats.ToString();
                    break;
                case 2:
                    return this.AvgTime.ToString();
                    break;
                case 3:
                    return this.AvgScore.ToString();
                    break;
                //case 4:
                //    return this.TotalTransferred.ToString();
                //    break;
                case 4:
                    return format( this.TotalChatTime );
                    break;
                default:
                    return "";
            }
        }
        private string format(long time)
        {
            long longValue = Convert.ToInt64(time);
            //D.HH:MM:SS
            //D为天，HH为小时，MM为分钟，SS为秒
            long second = 0;
            long day = Math.DivRem(longValue, 60 * 60 * 24, out second);
            long hour = Math.DivRem(second, 60 * 60, out second);
            long minute = Math.DivRem(second, 60, out second);

            return string.Format("{0}.{1}:{2}:{3}", day, hour.ToString("00"), minute.ToString("00"), second.ToString("00"));
        }
    }
    public class ChatbotAgentEntityInfo
    {
        public IList<SessionChatDto> ChatbotAgentEntityList { get; set; }
    }

    public class ChatbotAgentWrap : BasicWrap<ChatbotAgentItem, ChatbotAgentInfo, ChatbotAgentEntityInfo>
    {
        
        public static ChatbotAgentInfo GetChatbotAgent(SearchCriteria search, ChatbotAgentEntityInfo entityInfo, bool ifEncode = true)
        {

            ChatbotAgentInfo result = new ChatbotAgentInfo();
            //UTCToLocal(ref entityInfo);

            int[] onlyBotStatus = new int[] { 0, 1, 2 };

            var hasScoreChatList = entityInfo.ChatbotAgentEntityList.Where(a => a.RatingGrade > 0);
         
            double totalAgentOnly = entityInfo.ChatbotAgentEntityList.Count(a => a.Status == 0 && a.ChatType == (int)EnumChatType.AgentOnly);
            double totalChatbotOnly = entityInfo.ChatbotAgentEntityList.Count(a => onlyBotStatus.Contains(a.Status) && a.ChatType == (int)EnumChatType.ChatbotOnly);
            double totalTransferred = entityInfo.ChatbotAgentEntityList.Count(a => a.Status == 0 && a.ChatType == (int)EnumChatType.ChatbotToAgent);
            // double totalChats = totalAgentOnly+ totalChatbotOnly+ totalTransferred;
            double totalChats = totalAgentOnly + totalChatbotOnly ;

            double totalAgentOnlyTime = entityInfo.ChatbotAgentEntityList.Where(a => a.Status == 0 && a.ChatType == (int)EnumChatType.AgentOnly).Sum(a => a.EndTime.Subtract(a.StartTime).TotalSeconds);
            double totalChatbotOnlyTime = entityInfo.ChatbotAgentEntityList.Where(a => onlyBotStatus.Contains(a.Status) && a.ChatType == (int)EnumChatType.ChatbotOnly).Sum(a => a.EndTime.Subtract(a.StartTime).TotalSeconds);
            double totalBotToAgentTime = entityInfo.ChatbotAgentEntityList.Where(a => a.Status == 0 && a.ChatType == (int)EnumChatType.ChatbotToAgent).Sum(a => a.EndTime.Subtract(a.StartTime).TotalSeconds);
            //double totalTime = totalAgentOnlyTime+ totalChatbotOnlyTime+ totalBotToAgentTime;
            double totalTime = totalAgentOnlyTime + totalChatbotOnlyTime ;

            double totalAgentOnlyScore = hasScoreChatList.Where(a => a.Status == 0 && a.ChatType == (int)EnumChatType.AgentOnly).Sum(a => a.RatingGrade);
            double totalChatbotOnlyScore = hasScoreChatList.Where(a => onlyBotStatus.Contains(a.Status) && a.ChatType == (int)EnumChatType.ChatbotOnly).Sum(a => a.RatingGrade);
            double totalBotToAgentScore = hasScoreChatList.Where(a => a.Status == 0 && a.ChatType == (int)EnumChatType.ChatbotToAgent).Sum(a => a.RatingGrade);
            //double totalScore = totalAgentOnlyScore + totalChatbotOnlyScore + totalBotToAgentScore;

            double totalScore = totalAgentOnlyScore + totalChatbotOnlyScore ;

            double totalHasScoreAgentOnly = hasScoreChatList.Count(a => a.Status == 0 && a.ChatType == (int)EnumChatType.AgentOnly);
            double totalHasScoreChatbotOnly = hasScoreChatList.Count(a => onlyBotStatus.Contains(a.Status) && a.ChatType == (int)EnumChatType.ChatbotOnly);
            double totalHasScoreBotToAgent = hasScoreChatList.Count(a => a.Status == 0 && a.ChatType == (int)EnumChatType.ChatbotToAgent);
            //double totalHasScoreChats = totalHasScoreAgentOnly+ totalHasScoreChatbotOnly+ totalHasScoreBotToAgent;
            double totalHasScoreChats = totalHasScoreAgentOnly + totalHasScoreChatbotOnly ;
                        
            result.Agent = new ChatbotAgentItem {
                startTime = search.startDate.ToString(search.dateFormat),
                endTime = search.endDate.ToString(search.dateFormat),
                startTimeDate = search.startDate,
                endTimeDate = search.endDate,
                LocalstrartTime = search.startDate,
                LocalendTime = search.endDate,
                xAxisName = search.startDate.ToString("MMM dd", CultureInfo.GetCultureInfo("en-US")),
                tableRowName = search.startDate.ToString(search.dateFormat),
                Type = "Agent",
                Chats = (int)totalAgentOnly,
                AvgTime = CalcAvg(Convert.ToInt64(totalAgentOnlyTime), 60* totalAgentOnly),
                AvgScore = CalcAvg(totalAgentOnlyScore, totalHasScoreAgentOnly),
                Transferred= totalTransferred
            };
            result.Bot = new ChatbotAgentItem
            {
                startTime = search.startDate.ToString(search.dateFormat),
                endTime = search.endDate.ToString(search.dateFormat),
                startTimeDate = search.startDate,
                endTimeDate = search.endDate,
                LocalstrartTime = search.startDate,
                LocalendTime = search.endDate,
                xAxisName = search.startDate.ToString("MMM dd", CultureInfo.GetCultureInfo("en-US")),
                tableRowName = search.startDate.ToString(search.dateFormat),
                Type = "Bot",
                Chats = (int)totalChatbotOnly,
                AvgTime = CalcAvg(Convert.ToInt64(totalChatbotOnlyTime), 60* totalChatbotOnly),
                AvgScore = CalcAvg(totalChatbotOnlyScore, totalHasScoreChatbotOnly),
                Transferred = totalTransferred
            };
            result.Chats = (int)totalChats;
            result.AvgTime = CalcAvg(Convert.ToInt64(totalTime), 60*totalChats);
            result.AvgScore = CalcAvg(totalScore, totalHasScoreChats);
            result.TotalTransferred = totalTransferred;
            result.dataType = EnumReportDataType.DataByTime;

            if (search.filterType == EnumFilterType.chatFilterType)
            {
                if (search.filterStr == "All Chats")
                {
                    result.Chats += Convert.ToInt32(totalTransferred);
                    result.AvgTime = CalcAvg(Convert.ToInt64(totalTime + totalBotToAgentTime), result.Chats * 60);
                    result.AvgScore = CalcAvg(totalScore+ totalBotToAgentScore, totalHasScoreChats+ totalHasScoreBotToAgent);

                    result.Agent.Chats += Convert.ToInt32(totalTransferred);
                    result.Agent.TotalChatTime = CalcuChatTimeService.GetAgentTotalTime(entityInfo.ChatbotAgentEntityList.ToList());
                    result.Agent.AvgTime = CalcAvg(result.Agent.TotalChatTime, 60 * result.Agent.Chats);
                    result.Agent.AvgScore = CalcAvg(totalAgentOnlyScore + totalBotToAgentScore, totalHasScoreAgentOnly+ totalHasScoreBotToAgent);

                    result.Bot.Chats += Convert.ToInt32(totalTransferred);
                    result.Bot.TotalChatTime = CalcuChatTimeService.GetBotTotalTime(entityInfo.ChatbotAgentEntityList.ToList());
                    result.Bot.AvgTime = CalcAvg(result.Bot.TotalChatTime, 60 * result.Bot.Chats);
                    result.Bot.AvgScore = CalcAvg(totalChatbotOnlyScore + totalBotToAgentScore, totalHasScoreChatbotOnly+ totalHasScoreBotToAgent);
                }
                else if (search.filterStr == "Exclude Chats from Bot to Agents")
                {
                    result.Agent.TotalChatTime = Convert.ToInt64(totalAgentOnlyTime);
                    result.Bot.TotalChatTime = Convert.ToInt64(totalChatbotOnlyTime);
                }
            }

            result.TotalChatTime = result.Agent.TotalChatTime + result.Bot.TotalChatTime;

            //watch.Stop();
            //System.Diagnostics.Debug.WriteLine("Calc Time: " + watch.Elapsed);

            return result;
        }

        #region export

        //search the New Export CSV Data for Chat Source Info by criteria
        public static NewExportCSVData GetExprotData(SearchCriteria search, ChatbotAgentEntityInfo entityInfo)
        {
            ChatbotAgentInfo info = GetChatbotAgent(search, entityInfo, false);
            info.dataList = new List<ChatbotAgentItem>();
            info.dataList.Add(info.Bot);
            info.dataList.Add(info.Agent);

            NewExportCSVData result = new NewExportCSVData(string.Empty, new List<NewCSVColumn>(), new DataTable());
            switch (search.dimensionType)
            {
                case EnumDimensionType.ByTime://by time
                case EnumDimensionType.ByDepartment://by department
                case EnumDimensionType.ChatbotChats://by department
                case EnumDimensionType.ChatbotAnswers://by department
                case EnumDimensionType.ChatbotHightFidenceAnswers://by department
                    {
                        result = GetExprotCSVData(search, info, info.FieldList);
                        break;
                    }
                case EnumDimensionType.RequestPage:
                    {
                        result = GetExprotCSVData(search, info, new List<string>() { info.FieldList[0] });
                        break;
                    }
            }
            return result;
        }

        #endregion

    }
}
